from rest_framework import serializers

from users.models import User


# 定制序列化类
class AdminAuthSerializer(serializers.ModelSerializer):
    # 由于token默认是没有的，需要手工定制
    username = serializers.CharField(label='用户名')
    token = serializers.CharField(label='jwt token', read_only=True)

    class Meta:
        model = User
        fields = ('id', 'username', 'password', 'token')
        # 由于password是自动生成的，所以属性的更改需要 extra_kwargs
        extra_kwargs = {
            "password": {
                "write_only": True
            }
        }

    # 对我们的用户名和密码进行二次校验
    # 由于我们这里涉及到多个字段的校验，所以用我们的方法三
    def validate(self, attrs):
        # 1 提取数据
        username = attrs['username']
        password = attrs['password']
        # 2 校验数据
        # 2-1 用户名检测
        try:
            user = User.objects.get(username=username, is_staff=True)
        except User.DoesNotExist:
            raise serializers.ValidationError('用户名不存在')
        # 2-2 密码检测 check_password()
        else:
            if not user.check_password(password):
                raise serializers.ValidationError('密码不正确')
            # 3 补充属性数据
            # 定位：方便我们后续对同一个校验成功的数据对象进行jwt生成
            attrs['user'] = user
        return attrs

    # 改造 create方法 -- 生成我们的 token
    def create(self, validated_data):
        # 1 提取经过认证的用户信息
        user = validated_data['user']
        # 2 在我们的认证用户的基础上创建token
        from rest_framework_jwt.settings import api_settings

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)  # 从指定数据对象中提前数据
        token = jwt_encode_handler(payload)  # 创建token
        # 3 将token附加在数据对象
        user.token = token
        return user


# 定制用户信息的序列化类
class UserInfoSerializer(serializers.ModelSerializer):
    # 获取四个直接从数据库中获取到的数据
    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'email')
